package gui;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.JToolBar;
import javax.swing.SwingUtilities;

import db.ConnectionPool;
import db.LogListener;
import db.PoolListener;
import db.SimpleLogger;

/**
 * the class of DBMonitor is a Swing Frame to 
 * display the state of Database
 * 
 * this class is SINGLETON
 * @author dakiler
 *
 */
public class DBMonitor extends JFrame implements ActionListener,PoolListener,LogListener
{
	private static DBMonitor instance;
	private DBMonitor()
	{		
		init();
	}
	
	public synchronized static DBMonitor getInstance()
	{
		if(instance==null)
		{
			instance=new DBMonitor();
		}
		return instance;
	}
	
	private JToolBar toolbar=new JToolBar();
	private JButton clearbutton=new JButton("clear");
	private JTabbedPane jtp=new JTabbedPane();
	private JTextArea pooltext=new JTextArea();
	private JTextArea opertext=new JTextArea();
	private ConnectionPool pool=ConnectionPool.getInstance();
	private SimpleLogger logger=SimpleLogger.getInstance();
	/**
	 * initialize the components
	 */
	private void init()
	{
		Container con=this.getContentPane();
		con.setLayout(new BorderLayout());
		
		toolbar.add(clearbutton);
		clearbutton.addActionListener(this);
		con.add(toolbar,BorderLayout.NORTH);
		
		pooltext.setEditable(false);
		opertext.setEditable(false);
		jtp.addTab("pool status",new JScrollPane(pooltext));
		jtp.addTab("facade opers", new JScrollPane(opertext));
		con.add(jtp,BorderLayout.CENTER);
		//add the components
		
		pool.addListener(this);
		logger.setListener(this);//add the listener
		
		
		//set the window
		this.setSize(400,300);
		this.moveToCenter();
		this.setLAF();
		this.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
		this.setTitle("db monitor");
		this.setVisible(true);
	}
	
	/**
	 * this method will move the JFrame to the center of the Screen
	 */
	private void moveToCenter()
	{
		Toolkit tk=Toolkit.getDefaultToolkit();
		Dimension dim=tk.getScreenSize();
		this.setLocation((int)dim.getSize().width/2-this.getWidth()/2,(int)dim.height/2-this.getHeight()/2);
	}
	
	private void setLAF()
	{
		try
		{
			javax.swing.UIManager.setLookAndFeel(javax.swing.UIManager.getSystemLookAndFeelClassName());
			SwingUtilities.updateComponentTreeUI(this);
		}
		catch(Exception e)
		{			
		}
	}
	
	public void actionPerformed(ActionEvent event)
	{
		if(event.getSource()==clearbutton)
		{
			opertext.setText("");
			pooltext.setText("");//clear the textarea
		}
	}
	
	/**
	 * append the log message to the textarea
	 */
	public void log(String message)
	{
		opertext.append(message);
	}

	@Override
	public void connectionAssign(int index)
	{
		pooltext.append("connection assign: "+index+"\n");
		display();
	}

	@Override
	public void connectionRevoke(int index) 
	{
		pooltext.append("connection revoke: "+index+"\n");
		display();
	}

	@Override
	public void connectionTimeout(int index)
	{
		pooltext.append("connection timeout: "+index+"\n");
		display();
	}
	
	private void display()
	{
		pooltext.append(this.getPoolStatus());
	}	
	
	/**
	 * this method will return the ConnectionPool's status
	 * @return
	 */
	private String getPoolStatus()
	{
		StringBuffer sb=new StringBuffer();
		sb.append(logger.getDateString());
		sb.append("\t");
		
		ArrayList<Boolean>flags=pool.getFlags();
		for(int i=0;i<flags.size();i++)
		{
			if(flags.get(i))
			{
				sb.append(".");
			}
			else
			{
				sb.append("X");
			}
		}
		sb.append("\n");
		return sb.toString();
	}
}
